﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Acoris.Rendering
{
    using System.Numerics;
    using Acoris.Media;

#if WIN2D
    using Microsoft.Graphics.Canvas;
    using Microsoft.Graphics.Canvas.Text;
#endif

    /// <summary>
    /// 
    /// </summary>
    public sealed class TextRun : TextElement
    {
        // pair kerning
        // 指的是英文字符的间距调整，否则r和n可能会连起来变成m
#if WIN2D
        /// <summary>
        /// 获取光标的位置
        /// </summary>
        /// <param name="characterIndex">指定要获取的字符位置</param>
        /// <param name="trailingSideOfCharacter">指定光标是否停留在字符后边</param>
        public void GetCaretPosition(int characterIndex, bool trailingSideOfCharacter, out Vector2 pos, out CanvasTextLayoutRegion region)
        {
            pos = TextLayout.GetCaretPosition(characterIndex, false, out region);

        }

        public CanvasTextLayoutRegion[] GetCharacterRegions(int index, int count)
        {
            return TextLayout.GetCharacterRegions(index,count);
        }
#endif

        #region TextElement Override


#if DEBUG
        // this method could call only in project Acoris.UWP
        public void CreateResource(IDrawingContext drawingContext)
        {
            CreateResources(drawingContext);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="drawingContext"></param>
        /// <param name="pos"></param>
        public void Render(IDrawingContext drawingContext, Vector2 pos)
        {
            // make composition
            Composition(this);

#if WIN2D
            var drawingSession = drawingContext.DrawingContext;
            drawingSession.DrawTextLayout(TextLayout, pos, ForegroundBrush);
#endif
        }
#endif

        /// <summary>
        /// 创建渲染依赖的资源
        /// </summary>
        /// <param name="factory">资源工厂</param>
        internal override void CreateResources(IDrawingContext drawingContext)
        {
            var factory = drawingContext.Factory;

            if (!CacheResult)
            {
                // 缓存所有绘图依赖资源
#if WIN2D
                ForegroundBrush = Cache(factory.GetBrush(this.Format
                                                             .Foreground));
                TextFormat = Cache(factory.GetTextFormat(this.Format));
                TextLayout = Cache(factory.CreateTextLayout(this.Text, TextFormat));
#endif
            }

            // clean cache shading queue
            lock (LockObject)
            {
                while (CacheIssue.Count > 0)
                {
                    CachedShadingIssue issue = CacheIssue.Dequeue();
                    try
                    {
#if WIN2D
                        TextLayout.SetBrush(issue.index, issue.count, factory.GetBrush(issue.brush));
#endif
                    }
                    catch
                    {
                        // 放弃错误的位置
                    }
                }
            }
        }

        /// <summary>
        /// 开始渲染操作
        /// </summary>
        /// <param name="drawingContext"></param>
        internal override void Render(IDrawingContext drawingContext)
        {
            
            // make composition
            Composition(this);

#if WIN2D            
            var drawingSession = drawingContext.DrawingContext;
            drawingSession.DrawTextLayout(TextLayout, default(Vector2), ForegroundBrush);
#endif

        }



        #endregion
    }
}
